package Servers

import (
	"PBMessage"
	"fmt"

	. "misc/EventSystem"
	proto "misc/protobuf/proto"
	log "misc/seelog"
)

type ReadyRoom struct {
	UUID         string
	hallPlayers  []*HallPlayer
	readyPlayers []*PBMessage.ReadRoomPlayer
	Hall         *HallServer
	MapId        int32
	mapi         int
	HdData       *EventHandleFuncData
}

func NewReadyRoom(players []*HallPlayer, uuid string, hall *HallServer) *ReadyRoom {
	retReadyRoom := &ReadyRoom{
		UUID:         uuid,
		hallPlayers:  players,
		readyPlayers: make([]*PBMessage.ReadRoomPlayer, len(players)),
		Hall:         hall,
		mapi:         0,
	}
	for i := 0; i < len(players); i++ {
		players[i].PlayerState = EnumPlayerState_ReadyRoom
		players[i].readyRoom = retReadyRoom

		retReadyRoom.readyPlayers[i] = &PBMessage.ReadRoomPlayer{}
		retReadyRoom.readyPlayers[i].UserId = proto.Int64(players[i].GetUserId())
		retReadyRoom.readyPlayers[i].Account = proto.String(players[i].GetAccountModel().Account)
		retReadyRoom.readyPlayers[i].IsReady = proto.Bool(false)
		retReadyRoom.readyPlayers[i].SelectSpriteID = proto.String("")
		retReadyRoom.readyPlayers[i].SpriteSkinId = proto.String("")
		retReadyRoom.readyPlayers[i].NickName = proto.String(players[i].GetAccountModel().NickName)
		players[i].ReadRoomPlayer = retReadyRoom.readyPlayers[i]
	}
	retReadyRoom.HdData = GlobalEventManager.AddEventHandler("AIUnit.SelectHero", retReadyRoom.OnAISelectHero)

	return retReadyRoom
}

func (this *ReadyRoom) OnAISelectHero(args ...interface{}) {
	fmt.Println("OnAISelectHero", args[0].(int64))
	curPlayer := this.GetPlayer(args[0].(int64))
	curPlayer.GetReadyPlayerInfo().SelectSpriteID = proto.String(args[1].(string))
	curPlayer.GetReadyPlayerInfo().IsReady = proto.Bool(true)
}

func (readyRoom *ReadyRoom) GetPlayerIndex(userId int64) int {
	for i := 0; i < len(readyRoom.hallPlayers); i++ {
		if readyRoom.hallPlayers[i].GetUserId() == userId {
			return i
		}
	}
	return -1
}
func (this *ReadyRoom) GetPlayer(userId int64) *HallPlayer {
	return this.hallPlayers[this.GetPlayerIndex(userId)]
}

func (readyRoom *ReadyRoom) EnterRoomToClient() {
	enterReadyRoom := &PBMessage.SC_EnterReadyRoom{}
	enterReadyRoom.PlayerList = readyRoom.readyPlayers
	enterReadyRoom.RoomID = proto.String(readyRoom.UUID)
	for i := 0; i < len(readyRoom.hallPlayers); i++ {
		if readyRoom.hallPlayers[i].Sess != nil {
			readyRoom.hallPlayers[i].Sess.SendPacket(PBMessage.PBID_SC_EnterReadyRoom, enterReadyRoom)
		}
	}

	GlobalEventManager.CallEvent("ReadyRoom.New")
}

func (readyRoom *ReadyRoom) CS_SyncReadyPlayerStateHandler(msgData *PBMessage.CS_SyncReadyPlayerState) {
	index := readyRoom.GetPlayerIndex(msgData.GetUserId())
	if index == -1 {
		log.Info("error userid")
		return
	}
	readyRoom.readyPlayers[index].IsReady = proto.Bool(msgData.GetIsReady())
	readyRoom.readyPlayers[index].SelectSpriteID = proto.String(msgData.GetSelectSpriteID())
	readyRoom.readyPlayers[index].SpriteSkinId = proto.String(msgData.GetSpriteSkinId())
	readyRoom.MapId = msgData.GetMapID()

	readyRoom.SyncReadyRoomStateToClient()
	for i := 0; i < len(readyRoom.readyPlayers); i++ {
		if readyRoom.readyPlayers[i].GetIsReady() == false {
			return
		}
	}
	readyRoom.EnterReadyPlayerToGameScene()
}

func (readyRoom *ReadyRoom) SyncReadyRoomStateToClient() {
	syncReadyRoom := &PBMessage.SC_SyncReadyRoomState{}
	syncReadyRoom.PlayerList = readyRoom.readyPlayers
	syncReadyRoom.MapId = proto.Int32(readyRoom.MapId)
	for i := 0; i < len(readyRoom.hallPlayers); i++ {
		if readyRoom.hallPlayers[i].Sess != nil {
			readyRoom.hallPlayers[i].Sess.SendPacket(PBMessage.PBID_SC_SyncReadyRoomState, syncReadyRoom)
		}
	}
}

func (readyRoom *ReadyRoom) EnterReadyPlayerToGameScene() {
	enterGameScene := &PBMessage.SC_EnterGameScene{}
	enterGameScene.PlayerList = readyRoom.readyPlayers
	enterGameScene.MapId = proto.Int32(readyRoom.MapId)
	for i := 0; i < len(readyRoom.readyPlayers); i++ {
		readyRoom.Hall.RemovePlayer(readyRoom.hallPlayers[i].UserId)
		if readyRoom.hallPlayers[i].Sess != nil {
			readyRoom.hallPlayers[i].Sess.SendPacket(PBMessage.PBID_SC_EnterGameScene, enterGameScene)
		}
	}
	readyRoom.Hall.RemoveReadyRoom(readyRoom)

	readyRoom.Hall.GateServer.PushMessage(CommondMessage(
		CommonID_NewGameScene,
		"uuid", readyRoom.UUID,
		"hallPlayers", readyRoom.hallPlayers,
		"readyPlayers", readyRoom.readyPlayers,
		"mapid", readyRoom.MapId,
	))
}

func (readyRoom *ReadyRoom) BackPlayersToHall() {
	scBackToHall := &PBMessage.SC_BackReadyRoomToHall{}
	scBackToHall.BackType = proto.Int32(0)
	for i := 0; i < len(readyRoom.hallPlayers); i++ {
		player := readyRoom.hallPlayers[i]
		if player.PlayerState == EnumPlayerState_ReadyRoom {
			player.Sess.SendPacket(PBMessage.PBID_SC_BackReadyRoomToHall, scBackToHall)
		}
	}
}

func (this *ReadyRoom) Update(dt float64) {
	for i := 0; i < len(this.hallPlayers); i++ {
		if this.hallPlayers[i].AIUnit != nil {
			this.hallPlayers[i].AIUnit.Update()
		}
	}
}

func (this *ReadyRoom) OnExit() {

	GlobalEventManager.RemoveHandler("AIUnit.SelectHero", this.HdData)
	fmt.Println("ReadyRoom RemoveHandler ", this.HdData, GlobalEventManager.FindHandler("AIUnit.SelectHero"))

}
